import os
import sys
import ast
from collections import ChainMap
from tools.lbs_utils import *
# from tools.lbs_utils import baidu2amap, position_to_points, geo_to_location
"""
生成手艺人基因
手艺人基因用于交换订单搜索
"""
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(lineno)d: %(message)s')
logger = logging.getLogger(__name__)
df_orders = None
df_inventory = None


def get_yesterday(diff_days=1):
    today = datetime.date.today()
    one_day = datetime.timedelta(days=diff_days)
    ret_day = today - one_day
    return ret_day.strftime("%Y-%m-%d")


def baidu_to_amap(se):
    position = baidu2amap(float(se['lon']) / (10 ** 6), float(se['lat']) / (10 ** 6))
    lon, lat = position_to_points(position)
    return lon, lat


def correct_position(se):
    """
    检查并纠正错误坐标
    :param se:
    :return:
    """
    lon = float(se['lon'])
    lat = float(se['lat'])
    if lon <= 0 or lat <= 0:
        artisan_address = se['addr']
        position = geo_to_location(artisan_address, se['city_id'])
        if position is not None:
            lon, lat = position_to_points(position)
    return lon, lat


def gen_genes(se):
    """
    生成个体合法基因
    注意服务时间
    :param se:
    :return:
    """
    global df_inventory
    genes = [se.name]
    start_open_index = -1
    artisan_orders = df_orders[df_orders['artisan_id'] == se['artisan_id']].sort_values('half_hour')
    if len(artisan_orders) == 0:
        return None, None
    artisan_invent = list(df_inventory[df_inventory['artisan_id'] == se['artisan_id']].iloc[0])[1:]
    repeat = -1
    for i in range(48):
        if repeat <= 0:
            dna = 0
            if artisan_invent[i] == -1:
                dna = -1
            elif i in artisan_orders['half_hour'].values:
                # logger.debug(artisan_orders[artisan_orders['hour'] == i])
                now_order = artisan_orders[artisan_orders['half_hour'] == i].iloc[0]
                repeat = math.ceil(now_order['prod_minute']/30) - 1
                order_index = artisan_orders[artisan_orders['half_hour'] == i].index[0]
                # index从0开始，加1与空闲时间区分
                dna = order_index + 1
            if dna >= 0 and start_open_index < 0:
                start_open_index = i
        else:
            repeat -= 1
        genes.append(dna)
    start_server_time = start_open_index * 30 * 60
    return genes, start_server_time


def get_lock_time(order_id, order_lock_time):
    try:
        lock_time = order_lock_time[order_id]
    except:
        lock_time = 0
    return lock_time


def get_travel_num(se):
    inventory = se['inventory']
    genes = se['genes']
    return get_lock_travel_num(inventory, genes)


def get_delay_num(se):
    inventory = se['inventory']
    genes = se['genes']
    return get_lock_delay_num(inventory, genes)


if __name__ == "__main__":
    # 北京、上海、杭州、深圳
    city_cds = [[1, 22], [895, 917], [3812, 3826], [4994, 5001]]
    cate_cds = ['tag_mei_rong', 'tag_mei_jia', 'tag_mei_jie', 'tag_wei_zheng']
    # 分城市+类目
    try:
        city_id = int(sys.argv[1]) - 1
    except:
        city_id = 0
    try:
        cate_id = int(sys.argv[2]) - 1
    except:
        cate_id = 0
    try:
        day_interval = int(sys.argv[3])
    except:
        day_interval = 1
    if city_id < 0:
        city_id = 0
    if cate_id < 0:
        cate_id = 0
    if day_interval < 1:
        day_interval = 1
    yesterday = get_yesterday(day_interval)
    target_file = '/data/disp/' + yesterday + '/artisans_' + str(city_id) + '_' + str(cate_id) + '.csv'
    if not os.path.isfile(target_file):
        try:
            df_inventory = pd.read_csv('/data/disp/' + yesterday + '/inventory.csv', error_bad_lines=False,
                                       warn_bad_lines=False,
                                       encoding='utf8')
            logger.debug('load inventory:' + str(len(df_inventory)))
        except:
            df_inventory = None
        try:
            df_inventory.drop('Unnamed: 0', axis=1, inplace=True)
        except:
            pass
        try:
            df_orders = pd.read_csv('/data/disp/' + yesterday + '/orders_' + str(city_id) + '_' + str(cate_id) + '.csv',
                                    error_bad_lines=False, warn_bad_lines=False, encoding='utf8')
            df_orders.drop('Unnamed: 0', axis=1, inplace=True)
            # 导出 out_channel 方便后去筛选不同外部源单
            df_artisans = df_orders[
                ['artisan_id', 'city_id', 'prod_cate_cd', 'artisan_lon', 'artisan_lat', 'addr', 'out_channel']].drop_duplicates(
                'artisan_id')
            df_artisans.rename({'artisan_lon': 'lon', 'artisan_lat': 'lat'}, axis=1, inplace=True)
            logger.debug('load orders:' + str(len(df_orders)))
        except Exception as e:
            logger.debug(e)
            df_orders = None
            df_artisans = None
        if df_artisans is not None:
            city = city_cds[city_id]
            cate = cate_cds[cate_id]
            df_artisans = df_artisans[(df_artisans['city_id'] >= city[0]) & (df_artisans['city_id'] <= city[1]) & (
                    df_artisans['prod_cate_cd'] == cate)]
            # 将百度坐标转换为高德
            df_artisans['lon'], df_artisans['lat'] = zip(*df_artisans.apply(baidu_to_amap, axis=1))
            # 检查非法坐标，并转换为真实坐标
            df_artisans['lon'], df_artisans['lat'] = zip(*df_artisans.apply(correct_position, axis=1))
            # 始终无法获取正确坐标的手艺人不参与计算
            df_artisans = df_artisans[(df_artisans['lon'] > 0) & (df_artisans['lat'] > 0)].reset_index(drop=True)
            # 为方便计算，将手艺人的最早开放时间设置为出发时间
            df_artisans['genes'], df_artisans['stop'] = zip(*df_artisans.apply(gen_genes, axis=1))
            df_artisans.dropna(subset=['genes'], inplace=True)

            # 补充没有路程锁定时间的记录
            df_artisans['inventory'] = df_artisans['artisan_id'].apply(get_inventory, df_inventory=df_inventory)
            # df_artisans['inventory'] = df_artisans.apply(gen_inventory, axis=1)
            # 生成订单的路程锁定时间
            df_artisans['travel_num'] = df_artisans.apply(get_travel_num, axis=1)
            # 生成订单的延迟时间
            df_artisans['delay_num'] = df_artisans.apply(get_delay_num, axis=1)

            df_artisans.to_csv(target_file)
            logger.debug('load artisans:' + str(len(df_artisans)))

            order_lock_time = dict(ChainMap(*df_artisans['travel_num'].apply(lambda x: ast.literal_eval(str(x)))))
            df_orders['id'] = df_orders.index + 1
            df_orders['travel_num'] = df_orders['id'].apply(get_lock_time, order_lock_time=order_lock_time)
            df_orders.to_csv('/data/disp/' + yesterday + '/orders_' + str(city_id) + '_' + str(cate_id) + '.csv')
            logger.debug('update orders:' + str(len(df_orders)))
